package insight.google.game.era.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.directwebremoting.annotations.RemoteMethod;

import org.directwebremoting.annotations.RemoteProxy;

import insight.google.game.era.bo.GameRoom;
import insight.google.game.era.bo.GameUser;
import insight.google.game.era.bo.card.GameCard;
import insight.google.game.era.core.ChatCenter;
import insight.google.game.era.core.GameCenterManager;
import insight.google.game.era.core.Util;
import insight.google.game.era.core.hub.PendingEvents;
import insight.google.game.era.data.GameCenterDataManager;
import insight.google.game.era.data.GameUserDataManager;
import insight.google.game.era.data.Room;
import insight.google.game.era.data.RoomDataManager;
import insight.google.game.era.data.SimpleRoomDataManager;
import insight.google.game.era.data.User;
import insight.google.game.era.data.UserDataManager;
import insight.google.game.era.mgr.FlowManager;
import insight.google.game.era.mgr.HistoryManger;

@RemoteProxy(name = "RoomService")
public class RoomServiceImpl implements RoomService {

	private static final Log log = LogFactory.getLog(RoomServiceImpl.class);

	@RemoteMethod
	public void fetchCards() {
		// TODO Auto-generated method stub

	}
	@RemoteMethod
	public void quitRoom() {
		log.info("quit room........REMOTE.....START");
		this.quitFromRoom(false,null);
		log.info("quit room........REMOTE ...FINISH");
	}
	
	
	public void forceUSertoQuitRoom(User user){
		this.quitFromRoom(false,user);
	}

	
	public void quitFromRoom(boolean isGameOver, User currGamePlayer) {
		log.info("quit from  room........internal method.....START");
		GameRoom room = null;
		User user = null;
		if(currGamePlayer != null){
			user = currGamePlayer;
		}else{
			user = Util.getUserBySession();
		}
		UserDataManager userDataManager = null;
		RoomDataManager roomDataManager = null;
		SimpleRoomDataManager simpleRoomDataManager = null;
		boolean isRoomDeleted = false;
		String currRoomName = "";
		try {
			currRoomName = user.getRoomName();
			roomDataManager = new RoomDataManager(Util.createTranscationHandler(), true);
			room = roomDataManager.findByName(user.getRoomName());
			if(!isGameOver){
				room.quit(user);

				if (room.getUserList().size() == 0) {
					roomDataManager.removeFromDataStore(room);
					isRoomDeleted = true;
				} else {
					roomDataManager.addToDataStore(room);
				}
				roomDataManager.commit();

				if (isRoomDeleted) {
					roomDataManager = new RoomDataManager(Util.createTranscationHandler(), true);
					roomDataManager.addToDataStore(new GameRoom(currRoomName));
					// roomDataManager.addToDataStore(room);
					roomDataManager.commit();
				} else {
					GameUserDataManager gameUserDataManager = new GameUserDataManager(Util.createTranscationHandler(), true);
					GameUser gameUser = gameUserDataManager.findByName(user.getName());
					gameUserDataManager.removeFromDataStore(gameUser);
					gameUserDataManager.commit();
					
				}
				userDataManager = new UserDataManager(Util.createTranscationHandler());
				if(currGamePlayer != null){
					user = userDataManager.findById(currGamePlayer.getId());
				}else{
					user = Util.getUserBySession(userDataManager.getTransactionHandler());
				}
				
				user.reset();
				userDataManager.addToDataStore(user);
				userDataManager.commit();
			}else{
				GameUser currUser = Util.getUserByNameAndRoom(room, user);
				currUser.setState(GameUser.STATE_DEAD);

				Collection<GameUser> players = room.getUserList();
		        Collection<GameUser> attackUsers = null;
		        List<String> userList = new ArrayList<String>();
		        for (GameUser gameUser : players) {
		        	if(!gameUser.getName().equals(currUser.getName())){
		        		attackUsers = room.getAttackableUsers(gameUser);
		        		userList = new ArrayList<String>();
		        		for (GameUser attackuser : attackUsers) {
		        			userList.add(attackuser.getName());
		        		}
		        		gameUser.setAttackUserList(userList);
		        		gameUser.setRegisterAttack(true);
		        	}
		        }
		        
				room.notifyUserQuit(currUser);
				roomDataManager.addToDataStore(room);
				roomDataManager.commit();
			}
			

			

			simpleRoomDataManager = new SimpleRoomDataManager(Util.createTranscationHandler());
			Room simpleRoom = simpleRoomDataManager.findByName(currRoomName);

			if (isRoomDeleted) {
				simpleRoom.reset();
				
			} else if (!isRoomDeleted && room != null
					) {
				simpleRoom.syncRoomData(room);
			}
			simpleRoomDataManager.addToDataStore(simpleRoom);
			simpleRoomDataManager.commit();
			
			

		} catch (Exception e) {
			log.error(e.getLocalizedMessage());
			e.printStackTrace();
		} finally {
			if (roomDataManager != null) {
				roomDataManager.close();
			}
			if (simpleRoomDataManager != null) {
				simpleRoomDataManager.close();
			}
		}
		log.info("is room deleted   " + isRoomDeleted);
		if (!isRoomDeleted && room != null
				&& room.getGameState() == room.GAME_OVER) {
			HistoryManger.getInstance().gameOver(currRoomName);
			if(user.getScriptProxy() != null){
				user.getScriptProxy().addFunctionCall("componentExecFunctionWithCall","mainframe_instance","userQuitRoom");
			}
			isRoomDeleted = true;
		}
		
		if (isRoomDeleted) {
			roomDataManager = new RoomDataManager(Util.createTranscationHandler());
			ChatCenter chatCenter = roomDataManager.findChatCenter(ChatCenter.HOST_ROOM, currRoomName);
			if(chatCenter != null){
				roomDataManager.removeFromDataStore(chatCenter);
			}
		}

		GameCenterManager gameCenterManager = GameCenterManager.getInstance();
		gameCenterManager.updateGameCenter();
		log.info("quit from room........internal  ...FINISH");
	}

	private void updateGameCenter() {
		GameCenterDataManager gameCenterdataManager = null;

		try {
			gameCenterdataManager = new GameCenterDataManager(Util.createTranscationHandler(),true);
			GameCenterManager gameCenter = GameCenterManager.getInstance();
//			gameCenter.dataVersion = gameCenter.dataVersion +1; 
			gameCenter.updateGameCenter();
			gameCenterdataManager.addToDataStore(gameCenter);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (gameCenterdataManager != null) {
				gameCenterdataManager.close();
			}
		}
	}

	@RemoteMethod
	public void sendCard(String jsId, String targets[], String cardId,
			int dataVersion) throws Exception{
		 Date startDate = new Date();
		 log.info("Start timeis " + startDate.toString());
		
		 UserDataManager userDataManager = null;
		 try {
		 userDataManager = new UserDataManager(Util
		 .createTranscationHandler());
		
		 User user = Util.getUserBySession(userDataManager
		 .getTransactionHandler());
		 RoomDataManager roomDataManager = new RoomDataManager(
		 userDataManager.getTransactionHandler());
		 SimpleRoomDataManager simpleRoomDataManager = new
		 SimpleRoomDataManager(
		 userDataManager.getTransactionHandler());
		 Room simpleRoom = simpleRoomDataManager.findByName(user
		 .getRoomName());
		 GameRoom room = roomDataManager.findByName(user.getRoomName());
		 GameUser gameUser = Util.getUserByNameAndRoom(room, user);
		 gameUser.setScriptProxy(user.getScriptProxy());
		
		 GameUserDataManager gameUserDataManager = new GameUserDataManager(
		 userDataManager.getTransactionHandler());
		 gameUser.setDataManager(gameUserDataManager);
		
		 Date findDate = new Date();
		 log.info("findByName timeis " + findDate.toString());
		 log.info("-----findByName compare:" + (findDate.getTime() -
		 startDate.getTime()) + "ms");
		
		 if (!room.checkDataVersion(dataVersion)) {
		 room.sendCard(jsId, gameUser, targets, cardId);
		 room.upgradeDataVersion();
		 }
			        
		 Date dispatchDate = new Date();
		 log.info("send card timeis " + dispatchDate.toString());
		 log.info("-----send card compare:" + (dispatchDate.getTime() -
		 startDate.getTime()) + "ms");
		
		 simpleRoom.syncRoomData(room);
		 simpleRoomDataManager.addToDataStore(simpleRoom);
		 roomDataManager.addToDataStore(room);
		 roomDataManager.commit();
		 } catch (Exception e) {
		 e.printStackTrace();
		 log.error(e.getLocalizedMessage());
		 throw e;
		 } finally {
		 if (userDataManager != null) {
		 userDataManager.close();
		 }
		 }
		 Date endDate = new Date();
		 log.info("END timeis " + endDate.toString());
		 log.info("-----on load compare:" + (endDate.getTime() -
		 startDate.getTime()) + "ms");
	}

	@RemoteMethod
	public void startGame(int dataVersion) throws Exception {
		 Date startDate = new Date();
		 log.info("Start timeis " + startDate.toString());
		
		 GameRoom room = null;
		 User user = null;
		 UserDataManager userDataManager = null;
		 RoomDataManager roomDataManager = null;
		 try {
			 userDataManager = new UserDataManager(Util
			 .createTranscationHandler());
			 user = Util.getUserBySession(userDataManager
			 .getTransactionHandler());
			 roomDataManager = new RoomDataManager(userDataManager
			 .getTransactionHandler());
			 room = roomDataManager.findByName(user.getRoomName());
			
			 Date findDate = new Date();
			 log.info("findByName timeis " + findDate.toString());
			 log.info("-----findByName compare:" + (findDate.getTime() -
			 startDate.getTime()) + "ms");
			
			 // Util.getUserByRoom(room);
			 if (!room.checkDataVersion(dataVersion)) {
			
			 // shuffle cards
			 room.shuffuleCards();
			 roomDataManager.addToDataStore(room);
			 roomDataManager.commit();
			
			 Date shuffuleDate = new Date();
			 log.info("shuffule card timeis " + shuffuleDate.toString());
			 log.info("-----shuffule card compare:" + (shuffuleDate.getTime() -
			 startDate.getTime()) + "ms");
			
			 // get room object for start.
			 userDataManager = new UserDataManager(Util
			 .createTranscationHandler());
			 user = Util.getUserBySession(userDataManager
			 .getTransactionHandler());
			 roomDataManager = new RoomDataManager(userDataManager
			 .getTransactionHandler());
			 room = roomDataManager.findByName(user.getRoomName());
			 GameUserDataManager gameUserDataManager = new GameUserDataManager(
			 userDataManager.getTransactionHandler());
			
			 Date findDate1 = new Date();
			 log.info("findByName 1 timeis " + findDate1.toString());
			 log.info("-----findByName 1 compare:" + (findDate1.getTime() -
			 startDate.getTime()) + "ms");
			
			 // dispatch cards
			 room.discardCard2All(room, user, gameUserDataManager);
			
			 Date dispatchDate = new Date();
			 log.info("dispatch card timeis " + dispatchDate.toString());
			 log.info("-----dispatch card compare:" + (dispatchDate.getTime() -
			 startDate.getTime()) + "ms");
			
			 room.upgradeDataVersion();
			 roomDataManager.addToDataStore(room);
			 roomDataManager.commit();
			
			 Date savingDate = new Date();
			 log.info("save room timeis " + savingDate.toString());
			 log.info("-----save room compare:" + (savingDate.getTime() -
			 startDate.getTime()) + "ms");
			
			 // get room object for start.
			 userDataManager = new UserDataManager(Util
			 .createTranscationHandler());
							
							
			 user = Util.getUserBySession(userDataManager
			 .getTransactionHandler());
			 roomDataManager = new RoomDataManager(userDataManager
			 .getTransactionHandler());
			 room = roomDataManager.findByName(user.getRoomName());
			
			 userDataManager = new UserDataManager(Util
			 .createTranscationHandler());
							
			 Date findDate2 = new Date();
			 log.info("findByName 2 timeis " + findDate2.toString());
			 log.info("-----findByName 2 compare:" + (findDate2.getTime() -
			 startDate.getTime()) + "ms");
			
			 // GameCenter.getInstance().sycnRoomCache(room);
			 FlowManager flowMgr = new FlowManager(room);
			
			 GameUser gameUser = Util.getUserByNameAndRoom(room, user);
			 gameUser.setScriptProxy(user.getScriptProxy());
			 GameUser kingUser = flowMgr.startGame(gameUser,
			 "current_player_instance");
			 room.setKingUser(kingUser);
			 //room.setFlowMgr(flowMgr);
			 room.setCurrentUserId(user.getId());
			
			 room.publicData(user);
			 roomDataManager.addToDataStore(room);
			 roomDataManager.commit();
			 }
		 } catch (Exception e) {
			 e.printStackTrace();
			 log.error(e.getLocalizedMessage());
			 throw e;
		 } finally {
			 if (roomDataManager != null) {
				 roomDataManager.close();
			 }
		 }
		 Date endDate = new Date();
		 log.info("END timeis " + endDate.toString());
		 log.info("-----on load compare:" + (endDate.getTime() -
		 startDate.getTime()) + "ms");

	}

	@RemoteMethod
	public void initRoom(String jsComponentId) {
		User user = Util.getUserBySession();
		if (user != null && user.getRoomId() != null) {
			Date startDate = new Date();
			log.info("Start timeis " + startDate.toString());
			// RoomDataManager roomDataManager = new RoomDataManager(Util
			// .createTranscationHandler());
			RoomDataManager roomDataManager = new RoomDataManager();
			GameRoom room = roomDataManager.findByName(user.getRoomName());
			room.initGameRoomForClient(jsComponentId, user);
			Date endDate = new Date();
			log.info("END timeis " + endDate.toString());
			log.info("-----init Room compare:"
					+ (endDate.getTime() - startDate.getTime()) + "ms");
		}

	}

	@RemoteMethod
	public void failToMatchCard(String jsComponentId, String cardName) throws Exception{
		 // TODO Auto-generated method stub
		 UserDataManager userDataManager = null;
		 try {
		 userDataManager = new UserDataManager(Util
		 .createTranscationHandler());
		
		 User user = Util.getUserBySession(userDataManager
		 .getTransactionHandler());
		 RoomDataManager roomDataManager = new RoomDataManager(
		 userDataManager.getTransactionHandler());
		 SimpleRoomDataManager simpleRoomDataManager = new
		 SimpleRoomDataManager(
		 userDataManager.getTransactionHandler());
		 Room simpleRoom = simpleRoomDataManager.findByName(user
		 .getRoomName());
		 GameRoom room = roomDataManager.findByName(user.getRoomName());
		
		 GameUser gameUser = Util.getUserByNameAndRoom(room, user);
		 gameUser.setScriptProxy(user.getScriptProxy());
		 boolean saveDyingUser = room.failToDoMatchCard(room, gameUser, jsComponentId, cardName);
		 if(saveDyingUser){
			 (new RoomServiceImpl()).quitFromRoom(true,null);
		 }else{
			 simpleRoom.syncRoomData(room);
			 simpleRoomDataManager.addToDataStore(simpleRoom);
			 roomDataManager.addToDataStore(room);
			 roomDataManager.commit();
		 }
		 } catch (Exception e) {
		 e.printStackTrace();
		 log.error(e.getLocalizedMessage());
		 throw e;
		 } finally {
		 if (userDataManager != null) {
		 userDataManager.close();
		 }
		 }
	}

	@RemoteMethod
	public void finishPlay(String jsId, int dataVersion) throws Exception{
		// TODO Auto-generated method stub
		 UserDataManager userDataManager = null;
		 try {
		 userDataManager = new UserDataManager(Util
		 .createTranscationHandler());
		
		 User user = Util.getUserBySession(userDataManager
		 .getTransactionHandler());
		 RoomDataManager roomDataManager = new RoomDataManager(
		 userDataManager.getTransactionHandler());
		 GameRoom room = roomDataManager.findByName(user.getRoomName());
		 // if (!room.checkDataVersion(dataVersion)) {
		 GameUser gameUser = Util.getUserByNameAndRoom(room, user);
		 gameUser.setRecievedPLayedCard(null);
		 gameUser.setScriptProxy(user.getScriptProxy());
		 gameUser.setState(GameUser.STATE_DROP);
		
		 // GameCenter.getInstance().sycnRoomCache(room);
		 FlowManager flowMgr = new FlowManager(room);
		 flowMgr.finishPlay(jsId, room, gameUser);
		 // }
		 roomDataManager.addToDataStore(room);
		 roomDataManager.commit();
		 } catch (Exception e) {
		 e.printStackTrace();
		 log.error(e.getLocalizedMessage());
		 throw e;
		 } finally {
		 if (userDataManager != null) {
		 userDataManager.close();
		 }
		 }
	}

	// @Override
	// @RemoteMethod
	// public void getPlayerCards(int dataVersion) {
	// GameRoom room= Util.getRoom();
	// if(!room.checkDataVersion(dataVersion)){
	// room.getPlayerCard();
	// // GameCenter.getInstance().sycnRoomCache(room);
	// GameCenter.getInstance().getRoomCacheManager().updateToCache(room);
	// }
	//		
	// }

	@Override
	@RemoteMethod
	public void getCharacterCards(int dataVersion) throws Exception{
        Date startDate = new Date();
        log.info("Start timeis " + startDate.toString());

		UserDataManager userDataManager = null;
		try {
			userDataManager = new UserDataManager(Util
					.createTranscationHandler());

			User user = Util.getUserBySession(userDataManager
					.getTransactionHandler());
			RoomDataManager roomDataManager = new RoomDataManager(
					userDataManager.getTransactionHandler());
			SimpleRoomDataManager simpleRoomDataManager = new SimpleRoomDataManager(
					userDataManager.getTransactionHandler());
			Room simpleRoom = simpleRoomDataManager.findByName(user
					.getRoomName());
			GameRoom room = roomDataManager.findByName(user.getRoomName());

	        Date findDate = new Date();
	        log.info("findByName timeis " + findDate.toString());
	        log.info("-----findByName compare:" + (findDate.getTime() - startDate.getTime()) + "ms");

	        if (!room.checkDataVersion(dataVersion)) {
				room.discardCharacterCards(user);
				// GameCenter.getInstance().sycnRoomCache(room);
			}
	        Date dispatchDate = new Date();
	        log.info("dispatch card timeis " + dispatchDate.toString());
	        log.info("-----dispatch card compare:" + (dispatchDate.getTime() - startDate.getTime()) + "ms");

	        simpleRoom.syncRoomData(room);
			simpleRoomDataManager.addToDataStore(simpleRoom);
			roomDataManager.addToDataStore(room);
			userDataManager.commit();
//			HistoryManger.getInstance().updateGameHistory4Characters(room);
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getLocalizedMessage());
			throw e;
		} finally {
			if (userDataManager != null) {
				userDataManager.close();
			}
		}
        Date endDate = new Date();
        log.info("END timeis " + endDate.toString());
        log.info("-----get character compare:" + (endDate.getTime() - startDate.getTime()) + "ms");
	}

	@Override
	@RemoteMethod
	public void getRoleCards(int dataVersion) throws Exception{
        Date startDate = new Date();
        log.info("Start timeis " + startDate.toString());
		UserDataManager userDataManager = null;
		GameRoom room = null;
		try {
			userDataManager = new UserDataManager(Util
					.createTranscationHandler());

			User user = Util.getUserBySession(userDataManager
					.getTransactionHandler());
			RoomDataManager roomDataManager = new RoomDataManager(
					userDataManager.getTransactionHandler());
			SimpleRoomDataManager simpleRoomDataManager = new SimpleRoomDataManager(
					userDataManager.getTransactionHandler());
			Room simpleRoom = simpleRoomDataManager.findByName(user
					.getRoomName());
			room = roomDataManager.findByName(user.getRoomName());

	        Date findDate = new Date();
	        log.info("findByName timeis " + findDate.toString());
	        log.info("-----findByName compare:" + (findDate.getTime() - startDate.getTime()) + "ms");
			
			if (!room.checkDataVersion(dataVersion)) {
				room.discardRoleCard(user);
				// GameCenter.getInstance().sycnRoomCache(room);
			}
	        Date dispatchDate = new Date();
	        log.info("dispatch card timeis " + dispatchDate.toString());
	        log.info("-----dispatch card compare:" + (dispatchDate.getTime() - startDate.getTime()) + "ms");
			
			simpleRoom.syncRoomData(room);
			simpleRoomDataManager.addToDataStore(simpleRoom);
			roomDataManager.addToDataStore(room);
			userDataManager.commit();

		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getLocalizedMessage());
			throw e;
		} finally {
			if (userDataManager != null) {
				userDataManager.close();
			}
		}
        Date endDate = new Date();
        log.info("END timeis " + endDate.toString());
        log.info("-----get role compare:" + (endDate.getTime() - startDate.getTime()) + "ms");

		HistoryManger.getInstance().createGameHistory(room);
//		this.updateGameCenter();
        Date histroyDate = new Date();
        log.info("History & save timeis " + histroyDate.toString());
        log.info("-----History & save compare:" + (histroyDate.getTime() - startDate.getTime()) + "ms");

	}

	@Override
	@RemoteMethod
	public void enableCharacterPolicy(String jsComponentId, String policyId,
			int dataVersion) {
		// TODO Auto-generated method stub
		// UserDataManager userDataManager = null;
		// try {
		// userDataManager = new UserDataManager(Util
		// .createTranscationHandler());
		//
		// User user = Util.getUserBySession(userDataManager
		// .getTransactionHandler());
		// RoomDataManager roomDataManager = new RoomDataManager(
		// userDataManager.getTransactionHandler());
		// SimpleRoomDataManager simpleRoomDataManager = new
		// SimpleRoomDataManager(
		// userDataManager.getTransactionHandler());
		// Room simpleRoom = simpleRoomDataManager.findByName(user
		// .getRoomName());
		// GameRoom room = roomDataManager.findByName(user.getRoomName());
		//
		// room.enableCharacterPolicy(jsComponentId, policyId);
		//
		// simpleRoom.syncRoomData(room);
		// simpleRoomDataManager.addToDataStore(simpleRoom);
		// roomDataManager.addToDataStore(room);
		// roomDataManager.commit();
		// } catch (Exception e) {
		// e.printStackTrace();
		// log.error(e.getLocalizedMessage());
		// } finally {
		// if (userDataManager != null) {
		// userDataManager.close();
		// }
		// }
	}

	@Override
	@RemoteMethod
	public void sendCardPolicy(String jsComponentId, String[] targets,
			String[] cards, int dataVersion) {
		// TODO Auto-generated method stub
		// UserDataManager userDataManager = null;
		// try {
		// userDataManager = new UserDataManager(Util
		// .createTranscationHandler());
		//
		// User user = Util.getUserBySession(userDataManager
		// .getTransactionHandler());
		// RoomDataManager roomDataManager = new RoomDataManager(
		// userDataManager.getTransactionHandler());
		// SimpleRoomDataManager simpleRoomDataManager = new
		// SimpleRoomDataManager(
		// userDataManager.getTransactionHandler());
		// Room simpleRoom = simpleRoomDataManager.findByName(user
		// .getRoomName());
		// GameRoom room = roomDataManager.findByName(user.getRoomName());
		//
		// if (!room.checkDataVersion(dataVersion)) {
		// room.execCharacterPolicy(jsComponentId, targets, cards);
		// }
		//
		// simpleRoom.syncRoomData(room);
		// simpleRoomDataManager.addToDataStore(simpleRoom);
		// roomDataManager.addToDataStore(room);
		// roomDataManager.commit();
		// } catch (Exception e) {
		// e.printStackTrace();
		// log.error(e.getLocalizedMessage());
		// } finally {
		// if (userDataManager != null) {
		// userDataManager.close();
		// }
		// }
	}

	@Override
	@RemoteMethod
	public void sendDropCards(String jsComponentId, String[] cards,
			int dataVersion) {
		 // TODO Auto-generated method stub
		 UserDataManager userDataManager = null;
		 try {
		 userDataManager = new UserDataManager(Util
		 .createTranscationHandler());
		
		 User user = Util.getUserBySession(userDataManager
		 .getTransactionHandler());
		 RoomDataManager roomDataManager = new RoomDataManager(
		 userDataManager.getTransactionHandler());
		 GameRoom room = roomDataManager.findByName(user.getRoomName());
		 GameUserDataManager gameUserDataManager = new GameUserDataManager(
		 userDataManager.getTransactionHandler());
		
		 GameUser gameUser = Util.getUserByNameAndRoom(room, user);
		 gameUser.setScriptProxy(user.getScriptProxy());
		 gameUser.setState(GameUser.STATE_PLAYER);
		
		 // GameCenter.getInstance().sycnRoomCache(room);
		 for (int i = 0; i < cards.length; i++) {
		 GameCard card = gameUser.findCardByGenratedId2(
		 gameUserDataManager, cards[i]);
		 gameUser.removeCard(card.getId());
		 }
		
		 // this.notifyUsersCardCount(currUser);
		 FlowManager flowMgr = new FlowManager(room);
		 flowMgr.finishPlay(jsComponentId, room, gameUser);
		
		 room.upgradeDataVersion();
		 roomDataManager.addToDataStore(room);
		 roomDataManager.commit();
		 } catch (Exception e) {
		 e.printStackTrace();
		 log.error(e.getLocalizedMessage());
		 } finally {
		 if (userDataManager != null) {
		 userDataManager.close();
		 }
		 }
	}

	@Override
	@RemoteMethod
	public void finishedRegisterAttack() {
		 // TODO Auto-generated method stub
		 UserDataManager userDataManager = null;
		 try {
		 userDataManager = new UserDataManager(Util
		 .createTranscationHandler());
		
		 User user = Util.getUserBySession(userDataManager
		 .getTransactionHandler());
		 RoomDataManager roomDataManager = new RoomDataManager(
		 userDataManager.getTransactionHandler());
		 GameRoom room = roomDataManager.findByName(user.getRoomName());
		 GameUser currentUser = Util.getUserByNameAndRoom(room, user);
		
		 currentUser.setRegisterAttack(false);
		
		 roomDataManager.addToDataStore(room);
		 roomDataManager.commit();
		 } catch (Exception e) {
		 e.printStackTrace();
		 log.error(e.getLocalizedMessage());
		 } finally {
		 if (userDataManager != null) {
		 userDataManager.close();
		 }
		 }
	}

	@Override
	@RemoteMethod
	public void userOnTurn() throws Exception{
		 UserDataManager userDataManager = null;
		 RoomDataManager roomDataManager = null;
		 try {
		 userDataManager = new UserDataManager(Util
		 .createTranscationHandler());
		 User user = Util.getUserBySession(userDataManager
		 .getTransactionHandler());
		 roomDataManager = new RoomDataManager(userDataManager
		 .getTransactionHandler());
		 GameRoom room = roomDataManager.findByName(user.getRoomName());
		 GameUser currentUser = Util.getUserByNameAndRoom(room, user);
		
		 if (currentUser != null && currentUser.getIsActive()
		 && currentUser.isOnTurn()) {
		
		 currentUser.setOnTurn(false);
		 room.upgradeDataVersion();
		 roomDataManager.addToDataStore(room);
		 roomDataManager.commit();
		
		 // get transaction again
		 userDataManager = new UserDataManager(Util
		 .createTranscationHandler());
		 user = Util.getUserBySession(userDataManager
		 .getTransactionHandler());
		 roomDataManager = new RoomDataManager(userDataManager
		 .getTransactionHandler());
		 room = roomDataManager.findByName(user.getRoomName());
		
		 currentUser = Util.getUserByNameAndRoom(room, user);
		 currentUser.setScriptProxy(user.getScriptProxy());
		
		 // on turn execution
		 FlowManager flowMgr = new FlowManager(room);
		 flowMgr.onTurn(room, currentUser, "current_player_instance");
		 room.setCurrentUserId(user.getId());
		 roomDataManager.addToDataStore(room);
		 roomDataManager.commit();
		 }
		 } catch (Exception e) {
		 e.printStackTrace();
		 log.error(e.getLocalizedMessage());
		 throw e;
		 } finally {
		 if (roomDataManager != null) {
		 roomDataManager.close();
		 }
		 }
	}

	@Override
	@RemoteMethod
	public void executionPendingEvent() throws Exception{
		 UserDataManager userDataManager = null;
		 RoomDataManager roomDataManager = null;
		 try {
		 userDataManager = new UserDataManager(Util
		 .createTranscationHandler());
		
		 User user = Util.getUserBySession(userDataManager
		 .getTransactionHandler());
		 roomDataManager = new RoomDataManager(userDataManager
		 .getTransactionHandler());
		 GameRoom room = roomDataManager.findByName(user.getRoomName());
		 GameUser gameUser = Util.getUserByNameAndRoom(room, user);
		
		 if (gameUser.getEventList() != null
		 && !gameUser.getEventList().isEmpty()
		 && gameUser.getHavePendingEvent()) {
		 // set event list to empty and save to data store
		 // in order to execution twice.
		 gameUser.setHavePendingEvent(false);
		 // gameUser.setEventList(new ArrayList<PendingEvents>());
		
		 room.upgradeDataVersion();
		 roomDataManager.addToDataStore(room);
		 roomDataManager.commit();
		
		 // get transaction again
		 userDataManager = new UserDataManager(Util
		 .createTranscationHandler());
		 user = Util.getUserBySession(userDataManager
		 .getTransactionHandler());
		 roomDataManager = new RoomDataManager(userDataManager
		 .getTransactionHandler());
		 room = roomDataManager.findByName(user.getRoomName());
		
		 gameUser = Util.getUserByNameAndRoom(room, user);
		 gameUser.setScriptProxy(user.getScriptProxy());
		
		 // pending event execution
		 List<PendingEvents> events = gameUser.getEventList();
		 gameUser.processPendingEvents(events);
		 gameUser.setEventList(new ArrayList<PendingEvents>());
		 
		 room.setCurrentUserId(user.getId());
		 roomDataManager.addToDataStore(room);
		 roomDataManager.commit();
		 }
		 } catch (Exception e) {
		 e.printStackTrace();
		 log.error(e.getLocalizedMessage());
		 throw e;
		 } finally {
		 if (roomDataManager != null) {
		 roomDataManager.close();
		 }
		 }
	}

	@Override
	@RemoteMethod
	public void activeHangUser() throws Exception{
		 UserDataManager userDataManager = null;
		 RoomDataManager roomDataManager = null;
		 try {
		 userDataManager = new UserDataManager(Util
		 .createTranscationHandler());
		
		 User user = Util.getUserBySession(userDataManager
		 .getTransactionHandler());
		 roomDataManager = new RoomDataManager(userDataManager
		 .getTransactionHandler());
		 GameRoom room = roomDataManager.findByName(user.getRoomName());
		 GameUser gameUser = Util.getUserByNameAndRoom(room, user);
		 gameUser.setScriptProxy(user.getScriptProxy());
		
		 if (gameUser.getIsHanged()) {
		 gameUser.setHanged(false);
		 gameUser.setActive(true);
		 gameUser.readyToPlay("current_player_instance");
		 
		 room.setCurrentUserId(user.getId());
		 room.upgradeDataVersion();
		 roomDataManager.addToDataStore(room);
		 roomDataManager.commit();
		 }
		 } catch (Exception e) {
		 e.printStackTrace();
		 log.error(e.getLocalizedMessage());
		 throw e;
		 } finally {
		 if (roomDataManager != null) {
		 roomDataManager.close();
		 }
		 }
	}

	@Override
	public void userDead() {
		// TODO Auto-generated method stub
		 UserDataManager userDataManager = null;
		 try {
		 userDataManager = new UserDataManager(Util
		 .createTranscationHandler());
		
		 User user = Util.getUserBySession(userDataManager
		 .getTransactionHandler());
		 RoomDataManager roomDataManager = new RoomDataManager(
		 userDataManager.getTransactionHandler());
		 GameRoom room = roomDataManager.findByName(user.getRoomName());
		 GameUser gameUser = Util.getUserByNameAndRoom(room, user);
		 gameUser.setScriptProxy(user.getScriptProxy());
		
		 gameUser.dead(room);
		 room.upgradeDataVersion();
		
		 roomDataManager.addToDataStore(room);
		 roomDataManager.commit();
		 } catch (Exception e) {
		 e.printStackTrace();
		 log.error(e.getLocalizedMessage());
		 } finally {
		 if (userDataManager != null) {
		 userDataManager.close();
		 }
		 }
	}

	// public void test(){
	// GameRoom room= Util.getRoom();
	//		
	// }

}
